package games.car;

import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class Panel extends Frame {

    private Image image = null;
    private games.car.Car car = new games.car.Car(games.car.Config.WINDOW_HEIGHT / 2 - 50, games.car.Config.WINDOW_HEIGHT - 50,true);
    private Level level = new Level();
    private List<games.car.Boom> booms = new ArrayList<>();
    private List<games.car.Road> roads = new ArrayList<>();
    private int score = 0;
    private int maxScore = 0;
    private Font scoreAddFont = new Font("宋体",Font.BOLD,15);
    private games.car.Voice voice = null;
    boolean voiceOff = false;
    private boolean showGetGold = false;
    private boolean showUseCover = false;
    private boolean showUseSpeed = false;
    private Prop leftProp = null;
    private Prop rightProp = null;

    public void init(){
        setIconImage(Toolkit.getDefaultToolkit().getImage("res/pic/logo.png"));
        setTitle("Fast Furious v" + games.car.Config.VERSION);
        int screenWidth = Toolkit.getDefaultToolkit().getScreenSize().width;
        int screenHeight = Toolkit.getDefaultToolkit().getScreenSize().height;
        setBounds(screenWidth / 2 - games.car.Config.WINDOW_WIDTH / 2, screenHeight / 2 - games.car.Config.WINDOW_HEIGHT / 2, games.car.Config.WINDOW_WIDTH, games.car.Config.WINDOW_HEIGHT);
        setBackground(games.car.Config.WINDOW_BACKGROUND_COLOR);
        setVisible(true);
        setResizable(false);
        enableInputMethods(false);
        addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                games.car.Config.close();
                level.clear();
                roads.clear();
                dispose();
                System.exit(0);
            }
        });
        addWindowFocusListener(new WindowAdapter() {
            @Override
            public void windowLostFocus(WindowEvent e) {
                if(car.isLive() && games.car.Config.state == games.car.Config.State.RUNNING){
                    games.car.Config.state = games.car.Config.State.PAUSE;
                    repaint();
                }
            }
        });
        addKeyListener(new Event());
        ThreadPaint tp = new ThreadPaint();
        new Thread(tp).start();

        try {
            maxScore = games.car.Config.MAX_SCORE;
        } catch (Exception e) {
            System.out.println("========积分记录读取失败");
            e.printStackTrace();
        }

        voice = new games.car.Voice(games.car.Config.BACKGROUND_VOICE);
    }

    private void start(){
        score = 0;
        leftProp = null;
        rightProp = null;
        level.load();
        for (int i = 2; i <= 8; i=i+2) {
            int y = 0;
            while (y < games.car.Config.WINDOW_HEIGHT){
                roads.add(new games.car.Road(games.car.Config.CAR_WIDTH * i,y));
                y = y + games.car.Config.ROAD_LINE_HEIGHT * 2;
            }
        }
    }

    public void paint(Graphics g) {
        if (voice != null && !voice.isAlive()) {
            voiceOff = true;
        }
        if (games.car.Config.soundOn && voiceOff) {
            voiceOff = false;
            voice = new games.car.Voice(games.car.Config.BACKGROUND_VOICE);
            voice.start();
        }
        if(games.car.Config.state == games.car.Config.State.RUNNING){
            //初始化字体
            g.setFont(scoreAddFont);

            //加载路面动画
//            for (Road road : roads) {
//                road.draw(g);
//            }
            roads.forEach(road -> road.draw(g));

            //加载道具框
            Color color = g.getColor();

            if(leftProp != null){
                g.setColor(Color.red);
                g.drawString("Q",8 + games.car.Config.CAR_WIDTH / 2 - 3, games.car.Config.WINDOW_HEIGHT - games.car.Config.CAR_HEIGHT - 8 - 5);
                g.drawRect(8, games.car.Config.WINDOW_HEIGHT - games.car.Config.CAR_HEIGHT - 8, games.car.Config.CAR_WIDTH, games.car.Config.CAR_HEIGHT);
                if(leftProp != null) {
                    g.drawImage(leftProp.getImg(),8 + (int)(games.car.Config.CAR_WIDTH * 0.15), games.car.Config.WINDOW_HEIGHT - games.car.Config.CAR_HEIGHT - 8 + (int)(games.car.Config.CAR_WIDTH * 0.15),(int)(games.car.Config.CAR_WIDTH * 0.75),(int)(games.car.Config.CAR_HEIGHT * 0.75),null);
                }
            }
            if(rightProp != null){
                g.setColor(Color.orange);
                g.drawString("E", games.car.Config.WINDOW_WIDTH - 8 - games.car.Config.CAR_WIDTH / 2 - 3, games.car.Config.WINDOW_HEIGHT - games.car.Config.CAR_HEIGHT - 8 - 5);
                g.drawRect(games.car.Config.WINDOW_WIDTH - games.car.Config.CAR_WIDTH - 8, games.car.Config.WINDOW_HEIGHT - games.car.Config.CAR_HEIGHT - 8, games.car.Config.CAR_WIDTH, games.car.Config.CAR_HEIGHT);
                if(rightProp != null){
                    g.drawImage(rightProp.getImg(), games.car.Config.WINDOW_WIDTH - games.car.Config.CAR_WIDTH - 8 + (int)(games.car.Config.CAR_WIDTH * 0.15), games.car.Config.WINDOW_HEIGHT - games.car.Config.CAR_HEIGHT - 8 + (int)(games.car.Config.CAR_WIDTH * 0.15),(int)(games.car.Config.CAR_WIDTH * 0.75),(int)(games.car.Config.CAR_HEIGHT * 0.75),null);
                }
            }

            //加载保护罩
            if(showUseCover){
                g.drawImage(Images.COVER_IMG,car.getX() - 4,car.getY() - 4, games.car.Config.CAR_WIDTH + 8, games.car.Config.CAR_HEIGHT + 8,null);
            }

            //加载加速效果
            if(showUseSpeed){
                g.drawImage(Images.SPEED_IMG,car.getX() - 4,car.getY() - 4, games.car.Config.CAR_WIDTH + 8, games.car.Config.CAR_HEIGHT + 8,null);
            }

            //加载玩家车辆动画
            if(car.isLive()){
                car.draw(g);
            }

            //加载电脑车辆动画
            for (int i = 0; i < level.getBootCar().size(); i++) {
                games.car.Car boot = level.getBootCar().get(i);
                if(boot.isLive()){
                    boot.draw(g);
                    if(boot.collision(car)){
                        games.car.Boom boom = new games.car.Boom(car.getX(),car.getY());
                        booms.add(boom);
                        if(showUseCover){
                            showUseCover = false;
                        }else{
                            car.dead();
                            showUseSpeed = false;
                            new Thread(new OverThread()).start();
                        }
                    }
                    if(!boot.isLive()){
                        if(car.isLive()){
                            score++;
                        }
                    }
                }
            }

            //加载道具动画
            Iterator<Prop> propIterator = level.getProps().iterator();
            while(propIterator.hasNext()){
                Prop prop = propIterator.next();
                if(prop.isLive()){
                    prop.draw(g);
                    if(prop.collision(car)){
                        if(prop.typeEq(Prop.Type.GOLD)){
                            score += games.car.Config.PROP_COIN_SCORE;
                            showGetGold = true;
                            new Thread(new Runnable() {
                                @Override
                                public void run() {
                                    try {
                                        Thread.sleep(1000);
                                    } catch (InterruptedException e) {
                                        e.printStackTrace();
                                    }
                                    showGetGold = false;
                                }
                            }).start();
                        }else if(prop.typeEq(Prop.Type.COVER)){
                            rightProp = prop;
                        }else if(prop.typeEq(Prop.Type.FIRE)){
                            leftProp = prop;
                        }else if(prop.typeEq(Prop.Type.SPEED)){
                            rightProp = prop;
                        }
                    }
                }else{
                    propIterator.remove();
                }
            }

//            //加载爆炸动画
//            for (Boom boom : booms) {
//                boom.draw(g);
//            }
            booms.forEach(boom -> boom.draw(g));

            //加载积分动画
            g.setColor(Color.green);
            g.drawString("得分:" + score, 5, 45);

            //加载获得道具动画
            if(showGetGold){
                g.drawString("+" + games.car.Config.PROP_COIN_SCORE,car.getX() + games.car.Config.CAR_WIDTH / 2 - 8,car.getY() - 5);
            }
            g.setColor(color);

        }else if(games.car.Config.state == games.car.Config.State.READY){
            Color c = g.getColor();
            g.setColor(Color.green);
            g.drawString("操作说明", games.car.Config.WINDOW_WIDTH / 2 - 20, 100);
            g.drawString("   W              ↑", games.car.Config.WINDOW_WIDTH / 2 - 40, 130);
            g.drawString("A S D 或 ← ↓ →", games.car.Config.WINDOW_WIDTH / 2 - 40, 145);
            g.drawString("操控小车躲避障碍物，吃掉宝石可获得更高积分", games.car.Config.WINDOW_WIDTH / 2 - 120, 170);
            g.drawString("按F1可打开背景音乐", games.car.Config.WINDOW_WIDTH / 2 - 50, 195);
            g.drawString("回车开始，空格暂停", games.car.Config.WINDOW_WIDTH / 2 - 48, 230);
            g.drawString("ENTER", games.car.Config.WINDOW_WIDTH / 2 - 17, 265);
            g.drawRect(games.car.Config.WINDOW_WIDTH / 2 - 20,250,47,20);
            g.drawString("by eara", games.car.Config.WINDOW_WIDTH - 50, games.car.Config.WINDOW_HEIGHT - 10);
            g.setColor(c);
        }else if(games.car.Config.state == games.car.Config.State.OVER){
            if(score > maxScore){
                maxScore = score;
            }
            Color c = g.getColor();
            g.setColor(Color.red);
            g.drawString("游戏结束", games.car.Config.WINDOW_WIDTH / 2 - 20, 100);
            g.drawString("您的积分", games.car.Config.WINDOW_WIDTH / 2 - 40, 130);
            g.drawString(score + "", games.car.Config.WINDOW_WIDTH / 2 + 40, 130);
            g.drawString("最高记录", games.car.Config.WINDOW_WIDTH / 2 - 40, 170);
            g.drawString(maxScore + "", games.car.Config.WINDOW_WIDTH / 2 + 40, 170);
            g.drawString("重新开始", games.car.Config.WINDOW_WIDTH / 2 - 20, 210);
            g.drawString("ENTER", games.car.Config.WINDOW_WIDTH / 2 - 17, 245);
            g.drawRect(games.car.Config.WINDOW_WIDTH / 2 - 20,230,47,20);
            g.setColor(c);
        }else if(games.car.Config.state == games.car.Config.State.PAUSE){
            Color c = g.getColor();
            g.setColor(Color.orange);
            g.drawString("游戏暂停", games.car.Config.WINDOW_WIDTH / 2 - 20, 100);
            g.drawString("您的积分", games.car.Config.WINDOW_WIDTH / 2 - 40, 130);
            g.drawString(score + "", games.car.Config.WINDOW_WIDTH / 2 + 40, 130);
            g.drawString("最高记录", games.car.Config.WINDOW_WIDTH / 2 - 40, 170);
            g.drawString(maxScore + "", games.car.Config.WINDOW_WIDTH / 2 + 40, 170);
            g.drawString("空格继续", games.car.Config.WINDOW_WIDTH / 2 - 20, 210);
            g.drawString("SPACE", games.car.Config.WINDOW_WIDTH / 2 - 17, 245);
            g.drawRect(games.car.Config.WINDOW_WIDTH / 2 - 20,230,47,20);
            g.setColor(c);
        }
    }

    public void update(Graphics g) {
        if (image == null) {
            image = this.createImage(games.car.Config.WINDOW_WIDTH, games.car.Config.WINDOW_HEIGHT);
        }
        Graphics gimage = image.getGraphics();
        Color c = gimage.getColor();
        gimage.setColor(games.car.Config.WINDOW_BACKGROUND_COLOR);
        gimage.fillRect(0, 0, games.car.Config.WINDOW_WIDTH, games.car.Config.WINDOW_HEIGHT);
        gimage.setColor(c);
        paint(gimage);
        g.drawImage(image, 0, 0, null);

    }

    private class ThreadPaint implements Runnable {

        public void run() {
            while (true) {
                if(games.car.Config.state == games.car.Config.State.RUNNING){
                    repaint();
                }
                try {
                    Thread.sleep(1000 / games.car.Config.FPS);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    private class OverThread implements Runnable {

        public void run() {
            games.car.Config.setProperties("MAX_SCORE",maxScore + "", "积分记录");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            games.car.Config.state = games.car.Config.State.OVER;
            level.clear();
            roads.clear();
            repaint();
        }
    }

    private class Event extends KeyAdapter {
        public void keyReleased(KeyEvent e) {
            car.keyReleased(e);
        }

        public void keyPressed(KeyEvent e) {
            if(e.getKeyCode() == KeyEvent.VK_ENTER){
                if(games.car.Config.state == games.car.Config.State.RUNNING || games.car.Config.state == games.car.Config.State.PAUSE){
                    return;
                }
                games.car.Config.state = games.car.Config.State.RUNNING;
                start();
                score = 0;
                car = new games.car.Car(games.car.Config.WINDOW_HEIGHT / 2 - 50, games.car.Config.WINDOW_HEIGHT - 50,true);
            }
            if(car.isLive() && e.getKeyCode() == KeyEvent.VK_SPACE){
                if(games.car.Config.state == games.car.Config.State.RUNNING){
                    games.car.Config.state = games.car.Config.State.PAUSE;
                    repaint();
                }else if(games.car.Config.state == games.car.Config.State.PAUSE){
                    games.car.Config.state = games.car.Config.State.RUNNING;
                }
            }
            if (e.getKeyCode() == KeyEvent.VK_F1) {
                if (games.car.Config.soundOn) {
                    voice.close();
                    games.car.Config.soundOn = false;
                } else {
                    games.car.Config.soundOn = true;
                    voiceOff = true;
                }

            }
            if (e.getKeyCode() == KeyEvent.VK_Q) {
                if(leftProp == null || !car.isLive()){
                    return;
                }
                if(leftProp != null && leftProp.typeEq(Prop.Type.FIRE)){
                    for (games.car.Car car1 : level.getBootCar()) {
                        car1.dead();
                        games.car.Boom boom = new games.car.Boom(car1.getX(),car1.getY());
                        booms.add(boom);
                        score++;
                    }
                    leftProp = null;
                }
            }
            if (e.getKeyCode() == KeyEvent.VK_E) {
                if(rightProp == null || !car.isLive()){
                    return;
                }
                if(rightProp.typeEq(Prop.Type.COVER)){
                    //使用保护罩道具
                    showUseCover = true;
                    rightProp = null;
                }else if(rightProp.typeEq(Prop.Type.SPEED)){
                    if(showUseSpeed){
                        return;
                    }
                    //使用加速道具
                    new Thread(new Runnable() {
                        @Override
                        public void run() {
                            car.speedUp();
                            showUseSpeed = true;
                            try {
                                Thread.sleep(games.car.Config.PROP_SPEED_TIME * 1000);
                            } catch (InterruptedException interruptedException) {
                                interruptedException.printStackTrace();
                            }
                            car.speedReset();
                            showUseSpeed = false;
                        }
                    }).start();
                    rightProp = null;
                }
            }
            car.keyPressed(e);
        }
    }

    public static void main(String[] args) {
        new Panel().init();
    }
}
